local SourceModifierList = require("util/sourcemodifierlist")

local function getl(table)
    local n = 0
    for k, v in pairs(table) do
        n = n + 1
    end
    return n
end

local maxdef = .9
local planardef = 10

local i26egotool = Class(function(self, inst)
    self.inst = inst
    self.kc = {}
    self.aw_worktype = 0

    self.damage = 30
    self.planardamage = 0
    self.def = .1
    self.planardef = 2
    self.choplv = 1
    self.mode = false --灯
    self.flytime = 0

    self.hh_blk = false
    self.TOPTER_heal = false

    self.resflytime = 0

    self._lunacy_sources = SourceModifierList(inst, false, SourceModifierList.boolean)

    self.unlock_hot = 2
    self.unlock_cold = 0
    -- 添加温度定时任务属性
    self.temperature_task = nil

    self:Act()
end)
function i26egotool:OnSave()
    return
    {
        damage       = self.damage,
        planardamage = self.planardamage,
        def          = self.def,
        planardef    = self.planardef,
        kc           = self.kc,
        chop         = self.choplv,
        hh_blk       = self.hh_blk,
        aw_worktype  = self.aw_worktype,
        unlock_hot   = self.unlock_hot,
        unlock_cold  = self.unlock_cold,
    }
end

function i26egotool:OnLoad(data)
    self.damage       = data.damage or 30
    self.planardamage = data.planardamage or 0
    self.def          = data.def or .1
    self.planardef    = data.planardef or 2
    self.kc           = data.kc or {}
    self.hh_blk       = data.hh_blk or false
    self.choplv       = data.chop or 10
    --self.aw_worktype    = data.aw_worktype or 0
    self:SetMode(data.aw_worktype or 0)
    self.unlock_hot  = data.unlock_hot or 2
    self.unlock_cold = data.unlock_cold or 0
    self:Act()
end

function i26egotool:Act()
    local inst = self.inst
    local armor = inst:AddComponent("armor")
    if armor.SetKeepOnFinished == nil then
        armor.keeponfinished = true
    else
        armor:SetKeepOnFinished(true)
    end

    local planardamage = inst:AddComponent("planardamage")
    -- local planardefense = inst:AddComponent("planardefense")   --手部装备目前不能加位面防御
    -- planardefense:SetBaseDefense(self.planardef)
    self:ReSet()
end

local function addbss(inst)
    -- local addbs = function()
    --     inst:AddComponent("blinkstaff")
    --     inst.components.blinkstaff:SetFX("sand_puff_large_front", "sand_puff_large_back")
    --     inst.components.blinkstaff.onblinkfn = function(staff, pos, caster)
    --         if caster then
    --             if caster.components.staffsanity then
    --                 caster.components.staffsanity:DoCastingDelta(-5)
    --             elseif caster.components.sanity ~= nil then
    --                 caster.components.sanity:DoDelta(-5)
    --             end
    --         end
    --         inst.components.rechargeable:Discharge(5)
    --     end
    -- end
    -- inst:AddComponent("rechargeable")
    -- inst.components.rechargeable:SetOnDischargedFn(function()
    --     inst:RemoveComponent("blinkstaff")
    -- end)
    -- inst.components.rechargeable:SetOnChargedFn(function()
    --     addbs()
    -- end)
    -- addbs()
end
function i26egotool:ReSet()
    local inst = self.inst
    inst.components.armor:InitIndestructible(self.def)
    inst.components.planardamage:SetBaseDamage(self.planardamage)
    inst.components.weapon:SetDamage(self.damage)
    if self.owner and self.owner:IsValid()
        and self.owner.components.planardefense then
        self.owner.components.planardefense:AddBonus(inst, self.planardef, "i26")
    end
    -- if self.hh_blk and inst.components.rechargeable == nil then
    --     if inst.components.equippable then
    --         inst.components.equippable.walkspeedmult = 1.05
    --     end
    --     --addbss(inst)
    -- end
    if self.hh_blk then
        if inst.components.equippable then
            inst.components.equippable.walkspeedmult = 1.05
        end
    end

    inst.components.tool:SetAction(ACTIONS.CHOP, self.choplv)
end

local needtb =
{
    "axe",             --		= "斧头",
    "minifan",         -- = "旋转的风扇",
    "shovel",          -- "铲子",	
    "pitchfork",       --	= "干草叉",
    "pickaxe",         --	= "鹤嘴锄",
    "hammer",          --		= "锤子",

    "spear",           --		= "长矛",
    "goldenshovel",    -- "黄金铲子",

    "goldenaxe",       --	= "黄金斧头",	

    "goldenpitchfork", --	= "黄金干草叉",
    "goldenpickaxe",   --	= "黄金鹤嘴锄",
    "farm_hoe",        --	= "园艺锄",
    "golden_farm_hoe", --	= "黄金园艺锄",
    "hambat",          -- = "火腿棒",

    "oar",             --		= "桨",	
    "oar_driftwood",   --	= "浮木桨",	

    --boomerang	= "回旋镖",
    "fence_rotator",                      --	= "栅栏击剑",
    "tentaclespike",                      --	= "触手尖刺",
    "whip",                               --		= "三尾猫鞭",
    "nightstick",                         -- = "晨星锤",
    "nightsword",                         --	= "暗夜剑",
    "batbat",                             --		= "蝙蝠棒",
    "moonglassaxe",                       -- = "月光玻璃斧",

    "multitool_axe_pickaxe",              --	= "多用斧镐",
    "ruins_bat",                          --	= "铥矿棒",
    "shieldofterror",                     --	= "恐怖盾牌",
    "glasscutter",                        --		= "玻璃刀",

    "oar_monkey",                         --	= "战桨",
    "malbatross_beak",                    -- = "邪天翁喙",
    "shovel_lunarplant",                  --	= "亮茄锄铲",	
    "pickaxe_lunarplant",                 -- = "亮茄粉碎者",
    "sword_lunarplant",                   -- = "亮茄剑",
    "voidcloth_scythe",                   -- = "暗影收割者",
    "firestaff",                          -- = "火魔杖",
    "icestaff",                           -- = "冰魔杖",
    "yellowstaff",                        -- = "唤星者魔杖",
    "opalstaff",                          -- = "唤月者魔杖",

    "cutless",                            --	= "木头短剑",
    "trident",                            --		= "刺耳三叉戟",
    "pocketwatch_weapon",                 -- = "警钟",
    --slingshot	= "可靠的弹弓",
    "spear_wathgrithr",                   --	= "战斗长矛",
    "wathgrithr_shield",                  --	= "战斗圆盾",
    "spear_wathgrithr_lightning",         -- = "奔雷矛",
    "spear_wathgrithr_lightning_charged", -- = "充能奔雷矛",

    -- halberd = "戟",
    -- machete = "砍刀",
    -- goldenmachete = "黄金砍刀",
    -- obsidianmachete = "黑曜石砍刀",
    "lucy",               -- = "露西斧",
    "lighter",            -- = "薇洛的打火机",
    --mosquitobomb = "蚊子炸弹",
    "dumbbell",           -- = "哑铃",
    "dumbbell_golden",    -- = "黄金哑铃",
    "dumbbell_marble",    -- = "大理石哑铃",
    "dumbbell_gem",       -- = "宝石哑铃",
    "dumbbell_heat",      -- = "热铃",
    "dumbbell_redgem",    -- = "火铃",
    "dumbbell_bluegem",   -- = "冰铃",
    "merm_tool",          -- = "劣质工具",
    "merm_tool_upgraded", -- = "不那么劣质的工具",
    --i26_laotie = "老铁",
    "rabbitkingspear",    -- = "兔王棍",
    "shadow_battleaxe",   -- = "暗影槌",
}
local function GetNeed(table)
    if next(table) then
        for k, v in pairs(needtb) do
            if not table[v] then
                return TUNING.I26RZW[v]
            end
        end
    else
        return "所有武器"
    end
    return false
end



--function i26egotool:RZ(item)    --熔铸
--    if not item or not item:IsValid() or not item.prefab then return false end
--    if self.kc[item.prefab] then
--        if self.inst.components.talker then
--            local str = GetNeed(self.kc)
--
--            local lvmax = getl(TUNING.I26RZW)
--            --TheNet:Say(lvmax)
--            local lvcur = getl(self.kc)
--            --TheNet:Say(lvcur)
--            local nnum = lvmax - lvcur
--
--            if str then
--                self.inst.components.talker:Say(str.."\n尚可被熔铸\n"..nnum.."把武器待熔铸")
--            else
--                self.inst.components.talker:Say("这简直就是天顶剑！")
--            end
--        end
--        return true
--    end
--    if item.prefab == "huohuo_flag" then self.hh_blk = true
--    elseif item.prefab == "firestaff" then self.unlock_hot = math.max(3, self.unlock_hot)
--    elseif item.prefab == "icestaff" then self.unlock_cold = math.max(1, self.unlock_cold)
--    elseif item.prefab == "yellowstaff" then self.unlock_hot = math.max(4, self.unlock_hot)
--    elseif item.prefab == "opalstaff" then self.unlock_cold = math.max(2, self.unlock_cold) end
--    self.kc[item.prefab] = true
--    self:Lvup_B(item)
--    self:Lvup_E(item)
--    self:ReSet()
--    self.inst:SayLv()
--    item:Remove()
--    return true
--end

-- 定义特殊武器的常量数组
local SPECIAL_WEAPONS = {
    "huohuo_flag",
    "firestaff",
    "icestaff",
    "yellowstaff",
    "opalstaff",
    -- 可以在这里添加更多的特殊武器
}
-- 检查物品是否是特殊武器
local function IsSpecialWeapon(prefab)
    for _, special_weapon in ipairs(SPECIAL_WEAPONS) do
        if prefab == special_weapon then
            return true
        end
    end
    return false
end

function i26egotool:RZ(item) --熔铸
    if not item or not item:IsValid() or not item.prefab then return false end
    -- 获取当前熔铸模式
    local fusion_mode = TUNING.I26_FUSION_MODE
    -- 检查是否已经熔铸过
    if self.kc[item.prefab] then
        if self.inst.components.talker then
            if fusion_mode == "standard" then
                local str = GetNeed(self.kc)
                local lvmax = getl(TUNING.I26RZW)
                local lvcur = getl(self.kc)
                local nnum = lvmax - lvcur

                if str then
                    self.inst.components.talker:Say(str .. "\n尚可被熔铸\n" .. nnum .. "把武器待熔铸")
                else
                    self.inst.components.talker:Say("这简直就是天顶剑！")
                end
            else
                -- unlimited 模式下的提示
                self.inst.components.talker:Say("此物品已经熔铸过了。")
            end
        end
        return true
    end
    -- 检查是否符合熔铸条件
    local can_fuse = false
    if fusion_mode == "standard" then
        can_fuse = TUNING.I26RZW[item.prefab] ~= nil
    elseif fusion_mode == "unlimited" then
        -- 优先检查是否为特殊武器
        if IsSpecialWeapon(item.prefab) then
            can_fuse = true
        else
            -- 放宽判断条件，只要是工具或者武器就可以
            can_fuse = (item:HasTag("weapon") or item:HasTag("tool"))
                or (item.components.weapon and item.components.weapon.damage and item.components.weapon.damage > 0)
                or (item.components.tool)
                or (item.components.walkspeedmult)
        end
    end
    if can_fuse then
        -- 特殊武器处理
        if item.prefab == "huohuo_flag" then
            self.hh_blk = true
        elseif item.prefab == "firestaff" then
            self.unlock_hot = math.max(3, self.unlock_hot)
        elseif item.prefab == "icestaff" then
            self.unlock_cold = math.max(1, self.unlock_cold)
        elseif item.prefab == "yellowstaff" then
            self.unlock_hot = math.max(4, self.unlock_hot)
        elseif item.prefab == "opalstaff" then
            self.unlock_cold = math.max(2, self.unlock_cold)
        end
        -- 标记物品已熔铸
        self.kc[item.prefab] = true
        self:Lvup_B(item)
        self:Lvup_E(item)
        self:ReSet()
        self.inst:SayLv()
        -- 如果物品正在被装备，重新应用效果
        if self.owner ~= nil and self.owner:IsValid() then
            self:CheckAdjustTemperature(self.owner)
        end

        item:Remove()
        return true
    else
        if self.inst.components.talker then
            self.inst.components.talker:Say("此物品无法熔铸。")
        end
        return false
    end
end

-- 装备武器
function i26egotool:EqiuipFn(owner)
    self.owner = owner
    if owner.components.planardefense then
        owner.components.planardefense:AddBonus(self.inst, self.planardef, "i26")
    end
    owner.droplaotie = self.inst
    ---- 确保先清理可能存在的旧任务
    if self.temperature_task ~= nil then
        self.temperature_task:Cancel()
        self.temperature_task = nil
    end

    -- 创建新的温度控制任务
    self.temperature_task = owner:DoPeriodicTask(1, function()
        -- 确保使用当前武器实例的解锁状态
        self:CheckAdjustTemperature(owner)
    end)

    -- 如果需要声音效果，可以从旧函数中复制这部分
    -- self.inst:ListenForEvent("i26dd", Lisfn1, owner)
    -- self.inst:ListenForEvent("i26s3start", Lisfn2, owner)
    -- self.inst:ListenForEvent("i26attacked", Lisfn22, owner)
    -- self.inst:ListenForEvent("i26s3hit", Lisfn3, owner)

    self.inst:SayLv()
end

-- 脱下武器
function i26egotool:UnEqiuipFn(owner)
    self.owner = nil
    if owner.components.planardefense then
        owner.components.planardefense:RemoveBonus(self.inst, "i26")
    end
    owner.droplaotie = self.inst

    -- 确保移除当前武器的温度任务
    if self.temperature_task ~= nil then
        self.temperature_task:Cancel()
        self.temperature_task = nil
    end

    -- 如果需要移除声音效果监听，可以从旧函数中复制这部分
    -- self.inst:RemoveEventCallback("i26dd", Lisfn1, owner)
    -- self.inst:RemoveEventCallback("i26s3start", Lisfn2, owner)
    -- self.inst:RemoveEventCallback("i26attacked", Lisfn22, owner)
    -- self.inst:RemoveEventCallback("i26s3hit", Lisfn3, owner)
end


function i26egotool:CheckAdjustTemperature(inst)
    if TUNING.I26_TEMPERATURE_CONTROL ~= "enabled" then return end
    -- 检查当前武器实例的熔铸状态
    local has_yellowstaff = self.kc["yellowstaff"] -- 唤星
    local has_opalstaff = self.kc["opalstaff"]     -- 唤月
    local has_firestaff = self.kc["firestaff"]     -- 火魔杖
    local has_icestaff = self.kc["icestaff"]       -- 冰魔杖
    -- 如果没有全部熔铸所需法杖，直接返回
    if not (has_yellowstaff and has_opalstaff and has_firestaff and has_icestaff) then
        return
    end
    self:AdjustTemperature(inst)
end

-- 调整温度效果
function i26egotool:AdjustTemperature(inst)
    if not inst.components.temperature then return end
    local current_temp = inst.components.temperature:GetCurrent()
    -- 移除旧的温度调节器
    inst.components.temperature:RemoveModifier("i26_temperature")
    -- 立即调整温度
    if current_temp > 60 then
        -- 温度过高，立即降至40度
        inst.components.temperature:SetTemperature(40)
    elseif current_temp < 10 then
        -- 温度过低，立即升至30度
        inst.components.temperature:SetTemperature(30)
    end
end

function i26egotool:Lvup_B(item)
    -- if item.prefab == "i26_laotie" and item.components.i26egotool then
    --     self.def        = math.min(self.def + item.components.i26egotool.def, maxdef)
    --     self.planardef  = math.min(self.planardef + item.components.i26egotool.planardef, planardef)
    --     return
    -- end
    if self.def < maxdef then
        self.def = math.min(self.def + .1, maxdef)
    end
    if self.planardef < planardef then
        self.planardef = math.min(self.planardef + 1, planardef)
    end
end

function i26egotool:Lvup_E(item)
    -- if item.prefab == "i26_laotie" and item.components.i26egotool then
    --     self.damage = self.damage + item.components.i26egotool.damage
    --     self.planardamage = self.planardamage + item.components.i26egotool.planardamage
    --     return
    -- end
    local weapon = item.components.weapon
    if weapon then
        local val = type(weapon.damage) == "number" and weapon.damage or 34
        local mult = 2
        if item.components.tool ~= nil and val < 34 then --工具判定
            mult = 4
            self.choplv = math.min(self.choplv + 1, 10)
        end
        self.damage = self.damage + math.max(val / mult, 1)
    end
    local planardamage = item.components.planardamage
    if planardamage then
        local val = planardamage.basedamage
        self.planardamage = self.planardamage + math.max(val / 2, 0)
    end
end

--
-- local function Lisfn1(inst)
--     local weapon = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
--     if not weapon or not weapon:HasTag("i26_laotie")
--     then return end
--     weapon.SoundEmitter:PlaySound("i26yl/sfx/i26dd","i26dd")
--     weapon.SoundEmitter:PlaySound("i26yl/sfx/i26dd","i26dd")
--     --TheNet:Say(1)
-- end
-- local function Lisfn2(inst)
--     local weapon = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
--     if not weapon or not weapon:HasTag("i26_laotie")
--     then return end
--     weapon.SoundEmitter:PlaySound("i26yl/sfx/i26s3_1","i26s3_1")
--     weapon.SoundEmitter:PlaySound("i26yl/sfx/i26s3_1","i26s3_1")
--     --TheNet:Say(2)
-- end
-- local function Lisfn22(inst)
--     local weapon = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
--     if not weapon or not weapon:HasTag("i26_laotie")
--     then return end
--     weapon.SoundEmitter:PlaySound("i26yl/sfx/i26s3_2","i26s3_2")
--     weapon.SoundEmitter:PlaySound("i26yl/sfx/i26s3_2","i26s3_2")
-- end
-- local function Lisfn3(inst)
--     local weapon = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
--     if not weapon or not weapon:HasTag("i26_laotie")
--     then return end
--     weapon.SoundEmitter:PlaySound("i26yl/sfx/i26s3_3","i26s3_3")
--     weapon.SoundEmitter:PlaySound("i26yl/sfx/i26s3_3","i26s3_3")

--     --TheNet:Say(3)
-- end
--

-- 发光
function i26egotool:EnableLunacy(enable, source)
    self._lunacy_sources:SetModifier(self.inst, enable, source)

    local mode = self._lunacy_sources:Get()

    if self.mode ~= mode and self.inst.ltanimfx ~= nil and self.inst.ltanimfx:IsValid() then
        self.mode = mode
        self.inst.ltanimfx.net_bloo:set(self.mode)
    end
end

function i26egotool:SpFx_land(x, z) --参考mcw特效生成
    local fxs = {
        hammer_mjolnir_crackle = { 0 / 255, 138 / 255, 255 / 255, 0.9 },
        hammer_mjolnir_cracklebase = { 0 / 255, 138 / 255, 255 / 255, 0.9 },
        hammer_mjolnir_cracklehit = { 0 / 255, 138 / 255, 255 / 255, 0.9 },
        cracklehitfx = { 0 / 255, 138 / 255, 255 / 255, 0.9 }
    }
    for k, v in pairs(fxs) do
        local fx = SpawnPrefab(k)
        fx.Transform:SetPosition(x, 0, z)
        fx.AnimState:SetAddColour(unpack(v))
        fx:ListenForEvent("animover", fx.Remove)
    end
end

-- 发射
local flytargets = {}
local flyworks = {}


function i26egotool:Throw(owner, tarpos)
    owner.components.inventory:DropItem(self.inst)

    self.attacker = owner
    self.dest = tarpos
    self.flytime = GetTime()
    self.inst.Physics:ClearCollidesWith(COLLISION.LIMITS)
    flytargets = {}
    flyworks = {}

    local x, y, z = self.inst.Transform:GetWorldPosition()
    local facing_angle = owner.Transform:GetRotation() * DEGREES

    local offset = 1
    self.inst.Transform:SetPosition(x + offset * math.cos(facing_angle), y + offset, z - offset * math.sin(facing_angle))
    local speed = 24
    self:RotateToTarget(self.dest)
    self.inst.Physics:SetMotorVel(speed, 0, 0)
    self.isover = false
    self.inst:StartUpdatingComponent(self)
    self.inst:AddTag("flying")
    local wdlv = self.inst.components.i26wendu:GetLv()
    self.inst.AnimState:PlayAnimation("spin" .. wdlv, true)

    if self.i26ltcttask ~= nil then
        self.i26ltcttask:Cancel()
        self.i26ltcttask = nil
    end
    self.TOPTER_heal = false
end

function i26egotool:DoFlyAOE(inst)
    local weapon = self.inst
    local x, y, z = weapon.Transform:GetWorldPosition()
    local radius = 2
    local AOE_RANGE_PADDING = 6
    local MUST_TAGS = { "_combat" }
    local CANT_TAGS = { "INLIMBO", "wall", "DECOR", "invisible", "FX",
        "notarget", "noattack", "playerghost", "player", "companion", "moonstorm_static" }

    if self.aw_worktype == 1 then
        self:Flyaw_a(inst, x, y, z)
    elseif self.aw_worktype ~= 0 then
        self:Flyaw_b(inst, x, y, z)
    end

    local mult = weapon.components.inventoryitem
        and weapon.components.inventoryitem:GetGrandOwner() ~= nil
        and .05 or .5

    inst.components.combat.ignorehitrange = true
    for k, v in pairs(TheSim:FindEntities(x, y, z, radius + AOE_RANGE_PADDING, MUST_TAGS, CANT_TAGS)) do
        if v:IsValid()
            and not flytargets[v]
            and not v:IsInLimbo()
            and v.components.health ~= nil
            and not v.components.health:IsDead()
            and v.components.combat ~= nil then
            local range = v:GetPhysicsRadius(0) + radius
            local px, py, pz = v.Transform:GetWorldPosition()
            if distsq(x, z, px, pz) <= range * range and
                (v.components.follower == nil or v.components.follower.leader == nil or not v.components.follower.leader:HasTag("player")) then
                inst.components.combat:DoAttack(v, weapon, nil, nil, mult)
                flytargets[v] = true
                self.TOPTER_heal = true
            end
        end
    end
    inst.components.combat.ignorehitrange = false
end

function i26egotool:DoAoeWork(inst, x, z, r)
    local CANT_TAGS = { "locomotor", "INLIMBO", "DECOR", "companion" }
    local ONE_TAGS = self.aw_worktype == 1 and { "CHOP_workable" }
        or {
            "CHOP_workable", "MINE_workable", "HAMMER_workable", "DIG_workable", "NPC_workable"
        }
    if self.aw_worktype == 1 then
        for k, v in pairs(TheSim:FindEntities(x, 0, z, r, { "pickable" }, CANT_TAGS)) do
            if v:IsValid()
                and not v:IsInLimbo()
                and v.components.pickable and v.components.pickable:CanBePicked()
            then
                local success, loot = v.components.pickable:Pick(TheWorld)
                if loot ~= nil then
                    for i, item in ipairs(loot) do
                        Launch(item, self.inst, 1)
                    end
                end
            end
        end
    end

    for k, v in pairs(TheSim:FindEntities(x, 0, z, r, nil, CANT_TAGS, ONE_TAGS)) do
        if v:IsValid()
            and not v:IsInLimbo()
            and v.components.workable
            and v.components.workable:CanBeWorked()
        then
            v.components.workable:WorkedBy_Internal(inst, 100)
            -- if v:IsValid() and v:HasTag("stump") then
            --     v:Remove()
            -- end
        end
    end

    if not TheWorld.Map:IsOceanTileAtPoint(x, 0, z) and TheWorld.Map:IsVisualGroundAtPoint(x, 0, z) then --池塘炸鱼
        for k, v in pairs(TheSim:FindEntities(x, 0, z, r, { "fishable" })) do
            if v:IsValid()
                and not v:IsInLimbo()
                and v.components.fishable
                and v.components.fishable:GetFishPercent() > 0
            then
                local x2, y2, z2 = v.Transform:GetWorldPosition()
                local fish = v.components.fishable:HookFish(inst)
                if fish ~= nil then
                    inst:PushEvent("fishingstrain")
                    local caughtfish = v.components.fishable:RemoveFish(fish)
                    if caughtfish then
                        if caughtfish.Physics ~= nil then
                            caughtfish.Physics:SetActive(true)
                            caughtfish.Physics:Teleport(x2, y2 + 2, z2)
                        else
                            caughtfish.Transform:SetPosition(x2, y2 + 2, z2)
                        end
                        inst:PushEvent("fishingcatch", {
                            build = caughtfish.build
                        })

                        -- if caughtfish.Physics ~= nil then
                        -- caughtfish.Physics:SetActive(true)
                        -- end
                        caughtfish.entity:Show()
                        if caughtfish.DynamicShadow ~= nil then
                            caughtfish.DynamicShadow:Enable(true)
                        end
                        caughtfish.persists = true
                        inst:PushEvent("fishingcollect", {
                            fish = caughtfish
                        })
                        --Launch(caughtfish, self.inst, 2)
                        Launch(caughtfish, self.inst)
                    end
                end
            end
        end
    else
        for _, v in ipairs(TheSim:FindEntities(x, 0, z, r, nil, { "INLIMBO", "outofreach", "DECOR" })) do
            if v:IsValid()
                and not v:IsInLimbo()
                and v:IsOnOcean(false)
            then
                if v.components.oceanfishable ~= nil then
                    if v.components.weighable ~= nil then
                        v.components.weighable:SetPlayerAsOwner(inst)
                    end
                    local projectile = v.components.oceanfishable:MakeProjectile()
                    local ae_cp = projectile.components.complexprojectile
                    if ae_cp then
                        ae_cp:SetHorizontalSpeed(16)
                        ae_cp:SetGravity(-30)
                        ae_cp:SetLaunchOffset(Vector3(0, 0.5, 0))
                        ae_cp:SetTargetOffset(Vector3(0, 0.5, 0))
                        ae_cp:Launch(inst:GetPosition(), projectile)
                    else
                        Launch2(projectile, self.inst, 3, 1, 1, 1, 3)
                    end
                elseif v.components.inventoryitem ~= nil then
                    Launch2(v, self.inst, 3, 1, 1, 1, 3)
                    v.components.inventoryitem:SetLanded(false, true)
                elseif v.waveactive then
                    v:DoSplash()
                end
            end
        end
        local angle = GetRandomWithVariance(-45, 20)
        local FX_RADIUS = r * 0.65
        for _ = 1, 4 do
            angle = angle + 90
            local ox = x + FX_RADIUS * math.cos(angle * DEGREES)
            local oz = z - FX_RADIUS * math.sin(angle * DEGREES)
            if TheWorld.Map:IsOceanTileAtPoint(ox, 0, oz) and not TheWorld.Map:IsVisualGroundAtPoint(ox, 0, oz) then
                SpawnPrefab("crab_king_waterspout").Transform:SetPosition(ox, 0, oz)
            end
        end
    end
end

--why？    尝试消耗人工时间，减少代码运行时间  --？  -- 油饼
function i26egotool:Flyaw_a(inst, x, y, z)
    local CANT_TAGS = { "locomotor", "INLIMBO", "DECOR", "companion" }
    for k, v in pairs(TheSim:FindEntities(x, 0, z, 2, { "pickable" }, CANT_TAGS)) do
        if v:IsValid()
            and not v:IsInLimbo()
            and not flyworks[v]
            and v.components.pickable and v.components.pickable:CanBePicked()
        then
            local success, loot = v.components.pickable:Pick(TheWorld)
            if loot ~= nil then
                for i, item in ipairs(loot) do
                    Launch(item, self.inst, 1)
                end
            end
            flyworks[v] = success
        end
    end
    for k, v in pairs(TheSim:FindEntities(x, 0, z, 1.5, { "CHOP_workable" }, CANT_TAGS)) do
        if v:IsValid()
            and not v:IsInLimbo()
            and not flyworks[v]
            and v.components.workable
            and v.components.workable:CanBeWorked()
        then
            v.components.workable:WorkedBy_Internal(inst, 100)
            -- if v:IsValid() and v:HasTag("stump") then
            --     v:Remove()
            -- end
            flyworks[v] = true
        end
    end
end

function i26egotool:Flyaw_b(inst, x, y, z)
    local CANT_TAGS = { "locomotor", "INLIMBO", "DECOR", "companion" }
    local ONE_TAGS = { "CHOP_workable", "MINE_workable", "HAMMER_workable", "DIG_workable", "NPC_workable" }
    for k, v in pairs(TheSim:FindEntities(x, 0, z, 1.5, nil, CANT_TAGS, ONE_TAGS)) do
        if v:IsValid()
            and not v:IsInLimbo()
            and not flyworks[v]
            and v.components.workable
            and v.components.workable:CanBeWorked()
        then
            v.components.workable:WorkedBy_Internal(inst, 100)
            -- if v:IsValid() and v:HasTag("stump") then
            --     v:Remove()
            -- end
            flyworks[v] = true
        end
    end
end

--

function i26egotool:DoLandAOE(inst)
    local weapon = self.inst
    local x, y, z = weapon.Transform:GetWorldPosition()
    local radius = 4
    local AOE_RANGE_PADDING = 6
    local MUST_TAGS = { "_combat" }
    local CANT_TAGS = { "INLIMBO", "wall", "DECOR", "invisible", "FX",
        "notarget", "noattack", "playerghost", "player", "companion", "moonstorm_static" }

    -- local fx = SpawnPrefab("i26bfx1")
    -- fx.Transform:SetPosition(x, y, z)
    -- local fx = SpawnPrefab("hammer_mjolnir_cracklebase")
    -- fx.Transform:SetPosition(x, y, z)
    -- fx:ListenForEvent("animover",fx.Remove)

    self:SpFx_land(x, z)
    local shenshang = weapon.components.inventoryitem
        and weapon.components.inventoryitem:GetGrandOwner() ~= nil

    --work
    if self.aw_worktype ~= 0 then
        self:DoAoeWork(inst, x, z, 4)
    end

    if inst.components.health:IsDead() then return end
    --

    inst.components.combat.ignorehitrange = true
    for k, v in pairs(TheSim:FindEntities(x, y, z, radius + AOE_RANGE_PADDING, MUST_TAGS, CANT_TAGS)) do
        if v:IsValid()
            and not v:IsInLimbo()
            and v.components.health ~= nil
            and not v.components.health:IsDead()
            and v.components.combat ~= nil then
            local range = v:GetPhysicsRadius(0) + radius
            local px, py, pz = v.Transform:GetWorldPosition()
            if distsq(x, z, px, pz) <= range * range and
                (v.components.follower == nil or v.components.follower.leader == nil or not v.components.follower.leader:HasTag("player")) then
                inst.components.combat:DoAttack(v, weapon, nil, nil, shenshang and .15 or 1.5)
            end
        end
    end
    inst.components.combat.ignorehitrange = false
end

function i26egotool:OnUpdate(dt)
    if not self.attacker or not self.attacker:IsValid() then
        self:OverFly()
        return
    elseif GetTime() - self.flytime > 2 or self.isover then
        self:OverFly()
        return
    end

    self:DoFlyAOE(self.attacker)

    local x, y, z = self.inst.Transform:GetWorldPosition()
    local xx, _, zz = self.dest:Get()
    if distsq(x, z, xx, zz) < 3 then
        self.isover = true
        --self:OverFly()
    end

    self.resflytime = self.resflytime + dt
    if self.resflytime > .2 then
        self.resflytime = 0
        flytargets = {}
        flyworks = {}
    end
end

function i26egotool:OverFly()
    self:DoLandAOE(self.attacker)
    local x, y, z = self.inst.Transform:GetWorldPosition()

    self.inst:StopUpdatingComponent(self)
    self.inst.Physics:CollidesWith(COLLISION.LIMITS)
    self.inst.Physics:Stop()
    self.inst:RemoveTag("flying")


    self.attacker = nil
    self.dest = nil
    self.inst.AnimState:PlayAnimation("ground_" .. self.inst.components.i26wendu:GetLv())
    if self.inst.components.inventoryitem and self.inst.components.inventoryitem:GetGrandOwner() == nil then
        self.inst.Transform:SetPosition(x, 0, z)
    end

    if self.i26ltcttask ~= nil then
        self.i26ltcttask:Cancel()
        self.i26ltcttask = nil
    end
    self.i26ltcttask = self.inst:DoTaskInTime(5, function()
        self.TOPTER_heal = false
    end)
end

function i26egotool:RotateToTarget(dest)
    local direction = dest - self.inst:GetPosition()
    direction:Normalize()
    local angle = math.acos(direction:Dot(Vector3(1, 0, 0))) / DEGREES
    self.inst.Transform:SetRotation(angle)
    self.inst:FacePoint(dest)
end

local str = {
    [0] = "无破坏",
    [1] = "砍、采",
    [2] = "全类型破坏",
}

function i26egotool:TrMode()
    local num = 0
    if self.aw_worktype > 1 then
        num = 0
    else
        num = self.aw_worktype + 1
    end

    self:SetMode(num)

    return true
end

function i26egotool:SetMode(num)
    self.aw_worktype = num
    self.inst.phlx:set(self.aw_worktype)
    if self.inst.components.talker then
        self.inst.components.talker:Say(str[self.aw_worktype] or "")
    end
end

function i26egotool:GetThrowHZ()
    return self.TOPTER_heal
end

return i26egotool
